home *** CD-ROM | disk | FTP | other *** search
/ Openstep 4.2 (Developer) / Openstep Developer 4.2.iso / NextDeveloper / Source / GNU / perl / Perl / ext / DynaLoader / dl_next.xs < prev    next >
Encoding:
Text File  |  1995-12-06  |  6.1 KB  |  287 lines

  1. /* dl_next.xs
  2.  * 
  3.  * Platform:    NeXT NS 3.2
  4.  * Author:    Anno Siegel (siegel@zrz.TU-Berlin.DE)
  5.  * Based on:    dl_dlopen.xs by Paul Marquess
  6.  * Created:    Aug 15th, 1994
  7.  *
  8.  */
  9.  
  10. /*
  11.     And Gandalf said: 'Many folk like to know beforehand what is to
  12.     be set on the table; but those who have laboured to prepare the
  13.     feast like to keep their secret; for wonder makes the words of
  14.     praise louder.'
  15. */
  16.  
  17. /* Porting notes:
  18.  
  19. dl_next.xs is itself a port from dl_dlopen.xs by Paul Marquess.  It
  20. should not be used as a base for further ports though it may be used
  21. as an example for how dl_dlopen.xs can be ported to other platforms.
  22.  
  23. The method used here is just to supply the sun style dlopen etc.
  24. functions in terms of NeXTs rld_*.  The xs code proper is unchanged
  25. from Paul's original.
  26.  
  27. The port could use some streamlining.  For one, error handling could
  28. be simplified.
  29.  
  30. Anno Siegel
  31.  
  32. */
  33.  
  34. #include "EXTERN.h"
  35. #include "perl.h"
  36. #include "XSUB.h"
  37.  
  38. #include "dlutils.c"    /* SaveError() etc    */
  39.  
  40. static char *dl_last_error = (char *) 0;
  41.  
  42. static char *dlerror()
  43. {
  44.     return dl_last_error;
  45. }
  46.  
  47. int dlclose(handle) /* stub only */
  48. void *handle;
  49. {
  50.     return 0;
  51. }
  52.  
  53. #if NS_TARGET_MAJOR >= 4
  54. #import <mach-o/dyld.h>
  55.  
  56. enum dyldErrorSource
  57. {
  58.     OFImage,
  59. };
  60.  
  61. static void TranslateError
  62.     (const char *path, enum dyldErrorSource type, int number)
  63. {
  64.     char errorBuffer[128];
  65.     unsigned int index;
  66.     static char *OFIErrorStrings[] =
  67.     {
  68.     "%s(%d): Object Image Load Failure\n",
  69.     "%s(%d): Object Image Load Success\n",
  70.     "%s(%d): Not an recognisable object file\n",
  71.     "%s(%d): No valid architecture\n",
  72.     "%s(%d): Object image has an invalid format\n",
  73.     "%s(%d): Invalid access (permissions?)\n",
  74.     "%s(%d): Unknown error code from NSCreateObjectFileImageFromFile\n",
  75.     };
  76. #define NUM_OFI_ERRORS (sizeof(OFIErrorStrings) / sizeof(OFIErrorStrings[0]))
  77.  
  78.     if ( dl_last_error ) {
  79.         safefree(dl_last_error);
  80.     }
  81.     switch (type)
  82.     {
  83.     case OFImage:
  84.     index = number;
  85.     if (index > NUM_OFI_ERRORS - 1)
  86.         index = NUM_OFI_ERRORS - 1;
  87.     sprintf(errorBuffer, OFIErrorStrings[index], path, number);
  88.     break;
  89.  
  90.     default:
  91.     sprintf(errorBuffer, "%s(%d): Totally unknown error type %d\n",
  92.         path, number, type);
  93.     break;
  94.     }
  95.     dl_last_error = safemalloc(strlen(errorBuffer)+1);
  96.     strcpy(dl_last_error, errorBuffer);
  97. }
  98.  
  99. static char *dlopen(char *path, int mode /* mode is ignored */)
  100. {
  101.     int dyld_result;
  102.     NSObjectFileImage ofile;
  103.     NSModule handle = NULL;
  104.  
  105.     dyld_result = NSCreateObjectFileImageFromFile(path, &ofile);
  106.     if (dyld_result != NSObjectFileImageSuccess)
  107.     TranslateError(path, OFImage, dyld_result);
  108.     else
  109.     {
  110.         // NSLinkModule will cause the run to abort on any link error's
  111.     // not very friendly but the error recovery functionality is limited.
  112.     handle = NSLinkModule(ofile, path, TRUE);
  113.     }
  114.     
  115.     return handle;
  116. }
  117.  
  118. void *
  119. dlsym(handle, symbol)
  120. void *handle;
  121. char *symbol;
  122. {
  123.     void *addr;
  124.  
  125.     if (NSIsSymbolNameDefined(symbol))
  126.     addr = NSAddressOfSymbol(NSLookupAndBindSymbol(symbol));
  127.     else
  128.         addr = NULL;
  129.  
  130.     return addr;
  131. }
  132.  
  133. #else /* NS_TARGET_MAJOR <= 3 */
  134.  
  135. #include <streams/streams.h>
  136. #include <mach-o/rld.h>
  137.  
  138. static NXStream *OpenError(void)
  139. {
  140.     return NXOpenMemory( (char *) 0, 0, NX_WRITEONLY);
  141. }
  142.  
  143. static void TransferError(NXStream *s)
  144. {
  145.     char *buffer;
  146.     int len, maxlen;
  147.  
  148.     if ( dl_last_error ) {
  149.         safefree(dl_last_error);
  150.     }
  151.     NXGetMemoryBuffer(s, &buffer, &len, &maxlen);
  152.     dl_last_error = safemalloc(len);
  153.     strcpy(dl_last_error, buffer);
  154. }
  155.  
  156. static void CloseError(NXStream *s)
  157. {
  158.     if ( s ) {
  159.       NXCloseMemory(s, NX_FREEBUFFER);
  160.     }
  161. }
  162.  
  163. static char *dlopen(char *path, int mode /* mode is ignored */)
  164. {
  165.     int rld_success;
  166.     NXStream *nxerr = OpenError();
  167.     AV * av_resolve;
  168.     I32 i, psize;
  169.     char *result;
  170.     char **p;
  171.  
  172.     av_resolve = GvAVn(gv_fetchpv(
  173.     "DynaLoader::dl_resolve_using", FALSE, SVt_PVAV));
  174.     psize = AvFILL(av_resolve) + 3;
  175.     p = (char **) safemalloc(psize * sizeof(char*));
  176.     p[0] = path;
  177.     for(i=1; i<psize-1; i++) {
  178.     p[i] = SvPVx(*av_fetch(av_resolve, i-1, TRUE), na);
  179.     }
  180.     p[psize-1] = 0;
  181.     rld_success = rld_load(nxerr, (struct mach_header **)0, p,
  182.                 (const char *) 0);
  183.     safefree((char*) p);
  184.     if (rld_success) {
  185.     result = path;
  186.     } else {
  187.     TransferError(nxerr);
  188.     result = (char*) 0;
  189.     }
  190.     CloseError(nxerr);
  191.     return result;
  192. }
  193.  
  194. void *
  195. dlsym(handle, symbol)
  196. void *handle;
  197. char *symbol;
  198. {
  199.     NXStream    *nxerr = OpenError();
  200.     unsigned long    symref = 0;
  201.  
  202.     if (!rld_lookup(nxerr, symbol, &symref)) {
  203.     TransferError(nxerr);
  204.     }
  205.     CloseError(nxerr);
  206.     return (void*) symref;
  207. }
  208.  
  209. #endif /* NS_TARGET_MAJOR >= 4 */
  210.  
  211. /* ----- code from dl_dlopen.xs below here ----- */
  212.  
  213.  
  214. static void
  215. dl_private_init()
  216. {
  217.     (void)dl_generic_private_init();
  218. }
  219.  
  220. MODULE = DynaLoader     PACKAGE = DynaLoader
  221.  
  222. BOOT:
  223.     (void)dl_private_init();
  224.  
  225.  
  226.  
  227. void *
  228. dl_load_file(filename)
  229.     char *    filename
  230.     CODE:
  231.     int mode = 1;
  232.     DLDEBUG(1,fprintf(stderr,"dl_load_file(%s):\n", filename));
  233.     RETVAL = dlopen(filename, mode) ;
  234.     DLDEBUG(2,fprintf(stderr," libref=%x\n", RETVAL));
  235.     ST(0) = sv_newmortal() ;
  236.     if (RETVAL == NULL)
  237.     SaveError("%s",dlerror()) ;
  238.     else
  239.     sv_setiv( ST(0), (IV)RETVAL);
  240.  
  241.  
  242. void *
  243. dl_find_symbol(libhandle, symbolname)
  244.     void *    libhandle
  245.     char *    symbolname
  246.     CODE:
  247.     char symbolname_buf[1024];
  248.     symbolname = dl_add_underscore(symbolname, symbolname_buf);
  249.     DLDEBUG(2,fprintf(stderr,"dl_find_symbol(handle=%x, symbol=%s)\n",
  250.     libhandle, symbolname));
  251.     RETVAL = dlsym(libhandle, symbolname);
  252.     DLDEBUG(2,fprintf(stderr,"  symbolref = %x\n", RETVAL));
  253.     ST(0) = sv_newmortal() ;
  254.     if (RETVAL == NULL)
  255.     SaveError("%s",dlerror()) ;
  256.     else
  257.     sv_setiv( ST(0), (IV)RETVAL);
  258.  
  259.  
  260. void
  261. dl_undef_symbols()
  262.     PPCODE:
  263.  
  264.  
  265.  
  266. # These functions should not need changing on any platform:
  267.  
  268. void
  269. dl_install_xsub(perl_name, symref, filename="$Package")
  270.     char *    perl_name
  271.     void *    symref 
  272.     char *    filename
  273.     CODE:
  274.     DLDEBUG(2,fprintf(stderr,"dl_install_xsub(name=%s, symref=%x)\n",
  275.         perl_name, symref));
  276.     ST(0)=sv_2mortal(newRV((SV*)newXS(perl_name, (void(*)())symref, filename)));
  277.  
  278.  
  279. char *
  280. dl_error()
  281.     CODE:
  282.     RETVAL = LastError ;
  283.     OUTPUT:
  284.     RETVAL
  285.  
  286. # end.
  287.